package com.koron.device.controller;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.lang.tree.Tree;
import cn.hutool.core.lang.tree.TreeNodeConfig;
import cn.hutool.core.lang.tree.TreeUtil;
import cn.hutool.core.util.StrUtil;
import com.koron.bean.base.Response;
import com.koron.bean.system.staff.vo.EamUser;
import com.koron.common.core.annocation.CasUser;
import com.koron.common.core.config.ThreadLocalContext;
import com.koron.device.bean.Equipment;
import com.koron.device.bean.EquipmentRobotDto;
import com.koron.device.bean.TGParams;
import com.koron.device.bean.twin.TwinEqBo;
import com.koron.device.bean.twin.TwinEqDto;
import com.koron.device.mapper.EquipmentMapper;
import com.koron.device.mapper.TypeParamsMapper;
import com.koron.device.service.EquipmentService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.koron.ebs.mybatis.ADOConnection;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import springfox.documentation.annotations.ApiIgnore;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Api(tags = "外部接口")
@RestController
@RequestMapping("/twin")
public class TwinController {

    @Autowired
    private EquipmentService equipmentservice;

    @ApiOperation("孪生查设备")
    @PostMapping("/queryEquipment")
    public Response queryEquipment(@RequestBody TwinEqBo twineq) {

        if (CollUtil.isEmpty(twineq.getCodes()) && CollUtil.isEmpty(twineq.getIds())) {
            return Response.fail("设备标识不能为空");
        }

        List<TwinEqDto> list = ADOConnection.runTask(ThreadLocalContext.get().getCurrDs(), factory->{
            List<TwinEqDto> twinEqDtos = factory.getMapper(EquipmentMapper.class).queryByIdInAndCodeIn(twineq);
            for (TwinEqDto d : twinEqDtos) {
                String runningState = null;
                if(StrUtil.isBlank(d.getRunningState())){
                    continue;
                }
                switch (d.getRunningState()) {
                    case "run":
                        runningState = "运行";
                        break;
                    case "wait_run":
                        runningState = "待投运";
                        break;
                    case "stop_run":
                        runningState = "退运";
                        break;
                    default:
                        runningState = null;
                }
                d.setRunningState(runningState);
            }
            return twinEqDtos;
        }, List.class);

        return Response.ok(list);
    }


    @GetMapping("/robotGetTreeLazy")
    @ApiOperation(value = "机器人-查询设备台账树形结构（懒加载）")
    public Response<List<EquipmentRobotDto>> robotGetTreeLazy(@CasUser @ApiIgnore EamUser user, @RequestParam(value = "parentId", required = false) String parentId) {
        return ADOConnection.runTask(user.getCurrDs(), equipmentservice, "robotGetTreeLazy", Response.class, parentId);
    }

    @GetMapping("/robotGetEqById")
    @ApiOperation(value = "机器人-根据台账Id查设备")
    public Response<EquipmentRobotDto> robotGetEqById(@CasUser @ApiIgnore EamUser user, @RequestParam("eqId") String eqId) {
        EquipmentRobotDto dto = ADOConnection.runTask(user.getCurrDs(), factory -> {
            return factory.getMapper(EquipmentMapper.class).robotGetEqById(eqId);
        }, EquipmentRobotDto.class);
        return Response.ok(dto);
    }


    @GetMapping("/getEqListByPump")
    @ApiOperation(value = "机器人-根据泵站id查询设备列表")
    public Response getEqListByPump(@CasUser @ApiIgnore EamUser user,
                                                       @RequestParam("pump") String pump,
                                                       @RequestParam(value = "paramName", defaultValue = "管理部门") String paramName ) {
        List<EquipmentRobotDto> resulit = ADOConnection.runTask(user.getCurrDs(), factory -> {
            List<TGParams> tgParams = factory.getMapper(TypeParamsMapper.class).queryByParamName(paramName);
            if (CollUtil.isEmpty(tgParams)) {
                return new ArrayList();
            }
            // 参数id
            List<String> paramId = tgParams.stream().map(TGParams::getId).collect(Collectors.toList());

            // 查询 前三层 的 设备 管理单位 台账节点
            EquipmentMapper mapper = factory.getMapper(EquipmentMapper.class);
            List<Equipment> node = mapper.queryByThreeLevel(paramId, pump);
            if (CollUtil.isEmpty(node)) {
                return new ArrayList();
            }
            // 节点全路径
            List<String> leftFullPathCode = node.stream().map(Equipment::getFullPathCode).collect(Collectors.toList());

            // 要构造树的台账数据
            List<EquipmentRobotDto> eqlist = mapper.queryByFullPathCodeLikeMore(leftFullPathCode);

            // 上层节点
            List<String> nodeId = new ArrayList<>();
            for (Equipment eq : node) {
                String tempFullPathCode =  new String();
                tempFullPathCode = eq.getFullPathCode();
                String topfreeId = StrUtil.replace(tempFullPathCode, eq.getId(), "");
                List<String> split = StrUtil.split(topfreeId, "/");
                nodeId.addAll(split);
            }
            nodeId = nodeId.stream().distinct().collect(Collectors.toList());
            List<Equipment> list = mapper.queryByIdIn(nodeId);
            for (Equipment eq : list) {
                eqlist.add(Convert.convert(EquipmentRobotDto.class, eq));
            }

            return eqlist;
        }, List.class);
        return Response.ok(resulit);
    }

    @GetMapping("/getEqTreeByPump")
    @ApiOperation(value = "机器人-根据泵站id查询设备树")
    public Response getEqTreeByPumpTree(@CasUser @ApiIgnore EamUser user,
                                                       @RequestParam("pump") String pump,
                                                       @RequestParam(value = "paramName", defaultValue = "管理部门") String paramName ) {
        List<EquipmentRobotDto> resulit = ADOConnection.runTask(user.getCurrDs(), factory -> {
            List<TGParams> tgParams = factory.getMapper(TypeParamsMapper.class).queryByParamName(paramName);
            if (CollUtil.isEmpty(tgParams)) {
                return new ArrayList();
            }
            // 参数id
            List<String> paramId = tgParams.stream().map(TGParams::getId).collect(Collectors.toList());

            // 查询 前三层 的 设备 管理单位 台账节点
            EquipmentMapper mapper = factory.getMapper(EquipmentMapper.class);
            List<Equipment> node = mapper.queryByThreeLevel(paramId, pump);
            if (CollUtil.isEmpty(node)) {
                return new ArrayList();
            }
            // 节点全路径
            List<String> leftFullPathCode = node.stream().map(Equipment::getFullPathCode).collect(Collectors.toList());

            // 要构造树的台账数据
            List<EquipmentRobotDto> eqlist = mapper.queryByFullPathCodeLikeMore(leftFullPathCode);

            // 上层节点
            List<String> nodeId = new ArrayList<>();
            for (Equipment eq : node) {
                String tempFullPathCode =  new String();
                tempFullPathCode = eq.getFullPathCode();
                String topfreeId = StrUtil.replace(tempFullPathCode, eq.getId(), "");
                List<String> split = StrUtil.split(topfreeId, "/");
                nodeId.addAll(split);
            }
            nodeId = nodeId.stream().distinct().collect(Collectors.toList());
            List<Equipment> list = mapper.queryByIdIn(nodeId);
            for (Equipment eq : list) {
                eqlist.add(Convert.convert(EquipmentRobotDto.class, eq));
            }

            return eqlist;
        }, List.class);

        List<Tree<String>> treeList = TreeUtil.build(resulit, "0", new TreeNodeConfig(),
                (treeNode, node) -> {
                    node.setId(treeNode.getId());
                    node.setParentId(treeNode.getParentId());

                    // 如果不想一个个putExtra，可以直接Bean 转 Map 遍历赋值
                    Map<String, Object> map = BeanUtil.beanToMap(treeNode);
                    for (Map.Entry<String, Object> entry : map.entrySet()) {
                        node.putExtra(entry.getKey() ,entry.getValue());
                    }

                });

        return Response.ok(treeList);
    }
}
